package cn.edu.wtbu.wtbu_music_server.controller;

import cn.edu.wtbu.wtbu_music_server.dto.R;
import cn.edu.wtbu.wtbu_music_server.entity.Album;
import cn.edu.wtbu.wtbu_music_server.entity.Music;
import cn.edu.wtbu.wtbu_music_server.service.AlbumService;
import cn.edu.wtbu.wtbu_music_server.service.MusicService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * 专辑模块业务功能接口
 * 1. 专辑添加
 * 2. 专辑修改
 * 3. 列表查询专辑（含分页）
 * 4. 删除专辑（级联删除专辑下所有歌曲）
 * 5. 获取专辑中所有歌曲数据
 */
@Tag(name = "专辑接口",description = "专辑模块相关的Rest接口")
@RequestMapping("/album")
@RestController
public class AlbumController extends BaseController{

    /**
     * 注入AlbumService和MusicService，用于处理相册和音乐相关的业务逻辑。
     */

    @Autowired
    private AlbumService albumService;
    @Autowired
    private MusicService musicService;

    /**
     * 处理添加专辑信息的请求。
     * 该方法接收一个专辑对象作为参数，尝试将其添加到数据库中。
     * 添加成功或失败后，会返回相应的消息。
     *
     * @param album 待添加的专辑对象，包含专辑的所有相关信息。
     * @return R 返回一个结果对象，其中包含了操作是否成功的信息以及相应的消息文本。
     */
    @Operation(summary = "添加专辑",description = "根据提供的专辑对象添加专辑信息")
    @PostMapping("/add")
    public R add(@RequestBody Album album) {
        // 尝试保存专辑对象到数据库，根据操作结果返回成功或失败的消息
        return albumService.save(album) ? R.ok().setMsg("添加成功") : R.fail().setMsg("添加失败");
    }

    /**
     * 更新专辑信息。
     * 该接口使用GET请求来更新专辑信息，通过传入一个专辑对象来更新数据库中的相应记录。
     *
     * @param album 待更新的专辑对象。该对象应包含需要更新的专辑信息。
     * @return 返回操作结果，成功则返回一个包含修改成功的消息的响应对象，失败则返回一个包含修改失败的消息的响应对象。
     */
    @Operation(summary = "更新专辑",description = "根据提供的专辑对象更新专辑信息")
    @PutMapping("/update")
    public R update(@RequestBody Album album) {
        // 根据专辑对象更新数据库中的记录，返回操作的成功或失败结果
        return albumService.updateById(album) ? R.ok().setMsg("修改成功") : R.fail().setMsg("修改失败");
    }

    /**
     * 获取专辑列表。
     * @param page 请求的页码
     * @param size 每页显示的数量
     * @return 返回包含专辑列表的数据。
     */
    @Operation(summary = "获取专辑列表",description = "根据提供的当前页码和每页数据条数分页查询专辑信息")
    @Parameters({
            @Parameter(name = "page",description = "当前页码",required = true),
            @Parameter(name = "size",description = "每页数据条数",required = true)
    })
    @GetMapping("/list")
    public R list(Integer page, Integer size) {
        List<Album> list = albumService.list(new Page<>(page, size));
        return R.ok().setData(list);
    }

    /**
     * 删除专辑及其关联的音乐。
     * @param id 要删除的专辑ID
     * @return 返回操作结果，成功则返回删除成功的消息，失败则返回删除失败的消息。
     */
    @Operation(summary = "删除专辑",description = "根据提供的专辑id删除专辑信息")
    @Parameter(name = "id",description = "专辑id",required = true)
    @Transactional
    @DeleteMapping("/delete/{id}")
    public R delete(@PathVariable Integer id) {
        // 先删除该专辑关联的音乐，再删除专辑本身
        musicService.remove(new QueryWrapper<Music>().eq("aid", id));
        return albumService.removeById(id) ? R.ok().setMsg("删除成功") : R.fail().setMsg("删除失败");
    }

    /**
     * 获取指定专辑的详细信息，包括关联的音乐列表。
     * @param id 指定的专辑ID
     * @return 返回包含专辑详细信息和关联音乐列表的数据。
     */
    @Operation(summary = "获取专辑信息",description = "根据提供的专辑id查询专辑信息")
    @Parameter(name = "id",description = "专辑id",required = true)
    @GetMapping("/info/{id}")
    public R info(@PathVariable Integer id) {
        // 获取专辑对象和其关联的音乐列表
        Album album = albumService.getById(id);
        List<Music> list = musicService.list(Wrappers.lambdaQuery(Music.class).eq(Music::getAid, id));
        list.forEach(m->m.setAlbum(album)); // 给每首音乐设置所属的专辑信息
        return R.ok().setData(list);
    }

}
